package org.pybaldaj.bot;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.GZIPInputStream;

import org.pybaldaj.ICell;
import org.pybaldaj.IField;
import org.pybaldaj.Move;

public class Bot {

	public Collection<Move> getAvailableMoves(IField f) {
		
		return null;
	}
	
	public void processDictionary(IField f) {
		int maxPoints = 0;
		String optWord = "";
		int movesCount = 0;
		
		try {
			FileInputStream fstream = new FileInputStream(
					"src/main/resources/dictionary.gz");
			GZIPInputStream in = new GZIPInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			while ((strLine = br.readLine()) != null) {
				String word = strLine.trim();
				
				Collection<List<ICell>> pathes = new LinkedList<List<ICell>>();
				findWordOnField(f, word, pathes);
				
				boolean exists = false;
				if (!pathes.isEmpty()) {
					
					for (List<ICell> path : pathes) {
						boolean flag= false;
						for (ICell cell : path) {
							if (cell.getChar() == '\0') {
								flag = true;
								break;
							}
						}
						if (!flag) {
							exists = true;
							break;
						}
					}
					
					if (exists) {
						continue;
					}
					
					System.out.println(word);
					
					movesCount += pathes.size();
					if( word.length() > maxPoints) {
						maxPoints = word.length();
						optWord = word;
					}
					
				}
			}
			in.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}
		System.out.println("Opt: " + optWord);
		System.out.println("Total moves: " + movesCount);
	}
	


	public void findWordOnField(IField f, String word, Collection<List<ICell>> pathes) {
		
		int s = f.getCells().size();
		
		for (int i = 0; i < s; i++) {
			
			
			if (Character.toLowerCase(f.getCell(i).getChar()) == Character.toLowerCase(word.charAt(0))) {
				LinkedList<ICell> curPath = new LinkedList<ICell>();
				curPath.add(f.getCell(i));
				findWordOnField(f, word.substring(1), f.getCell(i), false, curPath, pathes);
				curPath.removeLast();
			} else if (f.getCell(i).getChar() == '\0') {
				LinkedList<ICell> curPath = new LinkedList<ICell>();
				curPath.add(f.getCell(i));
				findWordOnField(f, word.substring(1), f.getCell(i), true, curPath, pathes);
				curPath.removeLast();
			} else {
				continue;
			}
		}
	}
	
	private void findWordOnField(IField f, String word, ICell startCell, boolean emptyCellUsed, LinkedList<ICell> curPath, Collection<List<ICell>> pathes) {
		
		if (word.isEmpty()) {
			pathes.add((List<ICell>) curPath.clone());
			return;
		}
		
		Collection<ICell> neighbours = f.getCellNeighbours(startCell);
		
		for (ICell cell : neighbours) {
			if (curPath.contains(cell)) {
				continue;
			}
			
			if (Character.toLowerCase(cell.getChar()) == Character.toLowerCase(word.charAt(0))) {
				curPath.add(cell);
				findWordOnField(f, word.substring(1), cell, emptyCellUsed, curPath, pathes);
				curPath.removeLast();
			} else if (!emptyCellUsed && cell.getChar() == '\0') {
				curPath.add(cell);
				findWordOnField(f, word.substring(1), cell, true, curPath, pathes);
				curPath.removeLast();
			} else {
				continue;
			}
		}
	}
}
